/**
*		@file StmtTable.cpp
*		@brief StmtTable class
*
*		@author Zhou Nan
*
*		@date 1/25/2012
*/
#include "StmtTable.h"

vector<StmtEntry*>	StmtTable::vp_stmt_entries_;
vector<StmtNum>     StmtTable::while_stmt_num_;
vector<StmtNum>     StmtTable::if_stmt_num_;
vector<StmtNum>     StmtTable::call_stmt_num_;
vector<StmtNum>     StmtTable::assign_stmt_num_;

// step1: create new StmtEntry, assign data
// step2: push StmtEntry into vp_stmt_entries
void StmtTable::AddStmtEntry(StmtNum stmt_num, TNode* p_tnode)
{
	StmtEntry* p_stmt_entry_temp = NULL;
	// add stmt
	p_stmt_entry_temp = new StmtEntry;
	p_stmt_entry_temp->stmt_num = vp_stmt_entries_.size()+1;
	p_stmt_entry_temp->p_tnode = p_tnode;
	p_stmt_entry_temp->p_gnode = NULL;
	p_stmt_entry_temp->proc_idx = 0;

	switch(p_tnode->type){
	case ASSIGN_TYPE:
		assign_stmt_num_.push_back(p_stmt_entry_temp->stmt_num);
		p_tnode->value = assign_stmt_num_.size();
		break;
	case CALL_TYPE:
		call_stmt_num_.push_back(p_stmt_entry_temp->stmt_num);
		break;
	case WHILE_TYPE:
		while_stmt_num_.push_back(p_stmt_entry_temp->stmt_num);
		break;
	case IF_TYPE:
		if_stmt_num_.push_back(p_stmt_entry_temp->stmt_num);
		break;
	}
	vp_stmt_entries_.push_back(p_stmt_entry_temp);
	return ;
}

void	StmtTable::SetStmtGNode(StmtNum stmt_num, GNode* p_gnode)
{
	vp_stmt_entries_[stmt_num-1]->p_gnode = p_gnode;
	return ;
}

void	StmtTable::SetStmtBlkNode(StmtNum stmt_num, BlkNode* p_blknode)
{
	vp_stmt_entries_[stmt_num-1]->p_blknode = p_blknode;
	return ;
}

TNode* StmtTable::GetStmtTNode(StmtNum stmt_num)
{
	return vp_stmt_entries_[stmt_num-1]->p_tnode;
}

GNode* StmtTable::GetStmtGNode(StmtNum stmt_num)
{
	return vp_stmt_entries_[stmt_num-1]->p_gnode;
}

BlkNode* StmtTable::GetStmtBlkNode(StmtNum stmt_num)
{
	return vp_stmt_entries_[stmt_num-1]->p_blknode;
}

TNode*	StmtTable::GetAssignTNode(AssignNum assign_num){
	return vp_stmt_entries_[assign_stmt_num_[assign_num-1]-1]->p_tnode;
}

GNode*	StmtTable::GetAssignGNode(AssignNum assign_num){
	return vp_stmt_entries_[assign_stmt_num_[assign_num-1]-1]->p_gnode;
}

TNode*	StmtTable::GetWhileTNode(WhileNum while_num){
	return vp_stmt_entries_[while_stmt_num_[while_num-1]-1]->p_tnode;
}

GNode*	StmtTable::GetWhileGNode(WhileNum while_num){
	return vp_stmt_entries_[while_stmt_num_[while_num-1]-1]->p_gnode;
}

TNode*	StmtTable::GetCallTNode(CallNum call_num){
	return vp_stmt_entries_[call_stmt_num_[call_num-1]-1]->p_tnode;
}

GNode*	StmtTable::GetCallGNode(CallNum call_num){
	return vp_stmt_entries_[call_stmt_num_[call_num-1]-1]->p_gnode;
}

TNode*	StmtTable::GetIfTNode(IfNum if_num){
	return vp_stmt_entries_[if_stmt_num_[if_num-1]-1]->p_tnode;
}

GNode*	StmtTable::GetIfGNode(IfNum if_num){
	return vp_stmt_entries_[if_stmt_num_[if_num-1]-1]->p_gnode;
}

void StmtTable::SetProcIdx(StmtNum stmt_num, ProcIdx proc_idx)
{
	vp_stmt_entries_[stmt_num - 1]->proc_idx = proc_idx;
	return;
}

ProcIdx StmtTable::GetProcIdx(StmtNum stmt_num)
{
	return vp_stmt_entries_[stmt_num - 1]->proc_idx;
}


string StmtTable::ToString()
{
	stringstream ss_result;
	ss_result << "StmtTable :\n";
	for( int i = 0; i < GetSize(); i++ )
	{
		ss_result << (vp_stmt_entries_[i]->stmt_num) << " : TNodeType : " << TNodeTypeToString(vp_stmt_entries_[i]->p_tnode->type) <<  ";\n\t GNodeType : " << TNodeTypeToString(vp_stmt_entries_[i]->p_gnode->g_type) << endl;
	}
	return ss_result.str();
}
